<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Controla el proceso de facturacion para estudiantes y empresas
 *
 * @author Eliu
 */
class Bo_Facturacion {

    public static $db;
    public static $user;

    /**
     * 
     * @param type $entity
     * @return null
     */
    function getNoFact($entity) {
        $f = self::$db->query_select("cllg_factura_serie", "STATUS=1 AND FK_ENTITY=" . $entity);
        if (count($f) > 0) {
            return $f[0];
        }
        return null;
    }

    /**
     * 
     * @param type $serie
     * @param type $entity
     * @return int
     */
    function getNextFactura($serie, $entity) {
        $f = self::$db->queryToArray("select max(NUMERO) No FROM cllg_factura WHERE FK_ENTITY=" . $entity .
                " AND SERIE=" . sqlValue($serie, "text"));

        if (count($f) > 0 && !isEmpty($f[0]["No"])) {
            return $f[0]["No"];
        } else {
            return 0;
        }
    }

    /**
     * 
     * @param type $idEmpresa
     * @return type
     */
    function getDatosEmpresa($idEmpresa) {
        $nit = getFieldValue(self::$db, "cllg_empresa", $idEmpresa, "EMPRESA_NIT", 1);
        $dir = getFieldValue(self::$db, "cllg_empresa", $idEmpresa, "EMPRESA_DIR", 1);
        $nombre = getFieldValue(self::$db, "cllg_empresa", $idEmpresa, "EMPRESA_NOMBRE_FACTU", 1);
        $r = self::$db->query_select("cllg_empresa", sprintf("ID=%s", $idEmpresa));
        $r = $r[0];
        $r["nombre"] = $nombre;
        $r["nit"] = $nit;
        $r["dir"] = $dir;
        return $r;
    }

    /**
     * Obtiene siguiente factura basado en el ID
     * @return int
     */
    function getNextIDFactura() {
        $f = self::$db->queryToArray("select max(ID) as No FROM cllg_factura");
        if (count($f) > 0 && !isEmpty($f[0]["No"])) {
            return $f[0]["No"];
        } else {
            return 1;
        }
    }

    /**
     * 
     * @param type $id
     * @return type array
     */
    function getEstudCuenta($id) {
        $rs = self::$db->query_select('cllg_account', "FK_STUDENT=$id");
        return $rs[0];
    }

    public function testFacturarEmpresa() {
        $datos = Array
            (
            "empresa" => 1,
            "cheque" => 10,
            "deposito" => 12,
            "tarjeta" => 100,
            "efectivo" => 100,
            "boleta" => "34234234",
            "status" => 1,
            "estudiantes" => Array
                (
                "0" => Array
                    (
                    "CARNET" => 130408084,
                    "NOMBRE" => "Lilian Ayde Mart?nez Due?as",
                    "PAGO_TOT" => 790,
                    "cargos" => Array
                        (
                        "0" => Array
                            (
                            "ID" => 1350,
                            "MONEDA" => 1,
                            "DESCRIPTION" => "Mensualidad de Aug",
                            "AMOUNT" => 590,
                            "PENAL" => 0.00,
                            "PENAL_REF" => 0.00,
                            "TOT" => 590.000,
                            "ABONO" => 590.000,
                            "DATE_LIMIT" => "01/01/2013",
                            "TIPO_CARGO" => "M"
                        ),
                        "1" => Array
                            (
                            "ID" => 1358,
                            "MONEDA" => 1,
                            "DESCRIPTION" => "inscripci?n Trimestral de Jul",
                            "AMOUNT" => 200.00,
                            "PENAL" => 0.00,
                            "PENAL_REF" => 0.00,
                            "TOT" => 200.000,
                            "ABONO" => 200.000,
                            "DATE_LIMIT" => "01/01/2013",
                            "TIPO_CARGO" => "I"
                        )
                    ),
                    "hashKey" => 004
                )
            ),
            "total" => 0,
            "fechapago" => "13/09/2013",
            "datoscheque" => Array
                (
                "numero" => 234234,
                "fecha" => "13/09/2013",
                "banco" => "ANTIGUA"
            )
        );
        $this->facturarEmpresa($datos);
    }

    /**
     * Guarda una nueva factura en base a un pago
     * Estructura del objeto: 
     * @param type $pagoEmpresa=array();
     * @return void
     */
    public function facturarEmpresa($pagoEmpresa) {
        header("Content-Type: application/json");
        try {
            $fac = $this->getNoFact(self::$user->entity);
            $next = $this->getNextFactura($fac["SERIE"], self::$user->entity);
            $iva = Sys_ConfigManager::getParameter("IVA");
            $totIva = $pagoEmpresa["total"] / ($iva + 1); //total/1.12
            $empresa = $pagoEmpresa['empresa'];
            $empresaArr = explode(" - ", $empresa);
            $idEmpresa = intval($empresaArr[0]);
            $datosEmpresa = $this->getDatosEmpresa($idEmpresa);

            $next++;
            $factura = array(
                "NUMERO" => $next,
                "SERIE" => sqlValue($fac["SERIE"], "text"),
                "FECHA" => sqlValue(date("Y-m-d", strtotime($pagoEmpresa["fechapago"])), "date"),
                "TOTAL" => sqlValue($pagoEmpresa["total"], "double"),
                "NOMBRE" => sqlValue($datosEmpresa["nombre"], "text"),
                "DIRECCION" => sqlValue($datosEmpresa["dir"], "text"),
                "EFECTIVO" => sqlValue($pagoEmpresa["efectivo"], "double"),
                "CHEQUE" => sqlValue($pagoEmpresa["cheque"], "double"),
                "DEPOSITO" => sqlValue($pagoEmpresa["deposito"], "double"),
                "NO_BOLETA" => sqlValue((!isset($pagoEmpresa["boleta"]) ? "" : $pagoEmpresa["boleta"]), "text"),
                "NIT" => sqlValue($datosEmpresa["nit"], "text"),
                "IVA" => sqlValue($totIva, "double"),
                "TIPO_PAGO" => sqlValue("-", "text"),
                "SUBTOTAL" => sqlValue($pagoEmpresa["total"] - $totIva, "double"),
                "FK_ENTITY" => self::$user->entity,
                "STATUS" => sqlValue($pagoEmpresa["status"], "int"),
                "FK_EMPRESA" => sqlValue($idEmpresa, "int"),
                'DOLARES' => 0,
                'TASA_CAMBIO' => 0);

            $infoCargos = array();
            $allCargos = array();
            foreach ($pagoEmpresa["estudiantes"] as $e) { //genera el detalle de la factura
                foreach ($e["cargos"] as $c) {
                    $c["CARNET"] = $e["CARNET"];
                    $c["FECHAPAGO"] = $pagoEmpresa["fechapago"];
                    $mes = intval(date("m", strtotime($c["DATE_LIMIT"])));
                    $tipo = $c["TIPO_CARGO"];
                    if (!isset($infoCargos[$tipo])) {
                        $infoCargos[$tipo] = array($mes => array());
                    } else if (!isset($infoCargos[$tipo][$mes])) {
                        $infoCargos[$tipo][$mes] = array();
                    }
                    if (!isset($infoCargos[$tipo][$mes][$e["CARNET"]])) {
                        $infoCargos[$tipo][$mes][] = array($e["CARNET"] => $c["ABONO"]);
                    }
                    $allCargos[] = $c;
                }
            }
            self::$db->query_insert("cllg_factura", $factura);

            $fkFact = $this->getNextIDFactura();
            $infoMeses = Sys_ConfigManager::getMeses();
            $tiposCargos = Sys_ConfigManager::getTiposCargos();
            $detalleFact = array();

            if (isset($factura["CHEQUE"]) && floatval($factura["CHEQUE"]) > 0) {
                $datosCheque = $pagoEmpresa["datoscheque"];
                $datosCheque["monto"] = $factura["CHEQUE"];
                $datosCheque["factura"] = $fkFact;
                $this->saveCheque($datosCheque);
            }
            foreach ($infoCargos as $tc => $mesArr) {
                foreach ($mesArr as $mesId => $arrEstPago) {
                    $nMes = $infoMeses[$mesId];
                    $tipoCargo = $tiposCargos[$tc];
                    $subtotal = 0;
                    $mapEst = array();
                    foreach ($arrEstPago as $estArr) {
                        foreach ($estArr as $estCarnet => $pago) {
                            if (!isset($mapEst[$estCarnet])) {
                                $mapEst[$estCarnet] = $pago;
                            } else {
                                $mapEst[$estCarnet] = floatval($mapEst[$estCarnet]) + floatval($pago);
                            }
                            $subtotal = $subtotal + floatval($pago);
                        }
                    }
                    $tEst = count($mapEst);
                    $detalleFact[] = array("DESCRIPCION" => sqlValue("$tipoCargo(s) de $nMes de $tEst Estudiante(s)", "text"),
                        "CANTIDAD" => sqlValue($tEst, "int"), "SUBTOTAL" => sqlValue($subtotal, "double"), "FK_FACTURA" => sqlValue($fkFact, "int"));
                }
            }

            foreach ($detalleFact as $d) {
                self::$db->query_insert("cllg_factura_detalle", $d);
            }
            $this->aplicarCargos($allCargos, $fkFact);
            $serie = $fac["SERIE"];
            echo json_encode(array("factura" => "$serie-$next", "result" => 1));
        } catch (Exception $e) {
            echo json_encode(array("error" => "$e->getMessage()", "result" => 0));
        }
    }

    public function saveCheque($datosCheque) {
        $cheque = array("NUMERO" => sqlValue($datosCheque["numero"], "text"),
            "FECHA" => sqlValue(date("y-m-d"), "date"),
            "BANCO" => sqlValue($datosCheque["banco"], "text"),
            "FK_FACURA" => sqlValue($datosCheque["factura"], "int"),
            "FECHA_COBRO" => sqlValue($datosCheque["fecha"], "date"));
        self::$db->query_insert("cllg_cheque", $cheque);
    }

    /**
     * Devuelve el ultimo abono registrado
     * @return int
     */
    public function getLastAbono() {
        $f = self::$db->queryToArray("select max(ID) as No FROM cllg_abono");
        if (count($f) > 0 && !isEmpty($f[0]["No"])) {
            return $f[0]["No"];
        } else {
            return 1;
        }
    }

    /**
     * Aplica un listado de cargos, generando el abono respectivo y la relacion (cargo,abono,factura)
     * @param type $cargos
     */
    public function aplicarCargos($cargos, $idFactura = null) {
        $total = 0;
        $ccls = array();
        foreach ($cargos as $c) {
            //guardan los cargos a modificar
            $now = date("Y-m-d", strtotime($c["FECHAPAGO"]));
            $dataCargo = array(
                'TOTAL' => sqlValue($c["TOT"], 'double'),
                'TOTAL_PENDIENTE' => sqlValue(($c["TOT"] - $c["ABONO"]), 'double')
            );
            if (floatval($c["ABONO"]) == floatval($c["TOT"])) { // si cancela por completo el cargo
                $fPago = sqlValue($now, 'date');
                $dataCargo['DATE_PAYED'] = $fPago;
            }
            self::$db->query_update("cllg_cargo", $dataCargo, sprintf("ID=%s", $c["ID"]));

            if (!isset($ccls[$c["CARNET"]])) {
                $ccls[$c["CARNET"]] = $this->getEstudCuenta($c["CARNET"]);
            }
            $cc = $ccls[$c["CARNET"]];
            $abono = $c["ABONO"];
            $penal = $c["PENAL"];
            $total+=$abono;
            $dataAbono = array("FK_ACCOUNT" => sqlValue($cc["ID"], 'int'),
                "CREATED" => sqlValue($now, 'date'),
                "CREATED_BY" => sqlValue(self::$user->name, "text"),
                "DESCRIPTION" => sqlValue($c["DESCRIPTION"], 'text'),
                "TOTAL" => sqlValue($abono, 'float'),
                "CURR_BALANCE" => sqlValue(0.0, "float"),
                "PREV_BALANCE" => sqlValue(0.0, "float"),
                "PENALTY" => sqlValue($penal, "float"));
            self::$db->query_insert('cllg_abono', $dataAbono);

            $lastAbono = $this->getLastAbono();
            $relAbonoCargo = array("FK_CARGO" => $c["ID"],
                "FK_FACTURA" => $idFactura,
                "FK_ABONO" => $lastAbono,
                "MONTO" => $c["ABONO"],
                "CREATED" => sqlValue(date("y-m-d"), "date"),
                "CREATED_BY" => sqlValue(self::$user->name, "text"));
            self::$db->query_insert("cllg_mov_cargo", $relAbonoCargo);
        }
    }
    public function imprimir2(){
        $facNo = getParam("NUMERO");
        $arrFac = explode("-", $facNo);
        $strSerie = $arrFac[0];
        $strNumero = $arrFac[1];
        header("Location: ../invoices/format.php?SERIE={$strSerie}&NUMERO={$strNumero}");
    }
    
    public function imprimirBack() {
        $facNo = getParam("NUMERO");
        $arrFac = explode("-", $facNo);
        $strSerie = $arrFac[0];
        $strNumero = $arrFac[1];
        $strFecha = date("d") . '          ' . date("M") . '           ' . date("Y");
        $sinTotal = 0;

        $fac = self::$db->query_select("cllg_factura", sprintf("NUMERO='%s' AND SERIE='%s'", $strNumero, $strSerie));
        $getEmpName = self::$db->query_select("cllg_empresa", sprintf("ID='%s'", $fac[0]['FK_EMPRESA']));
        $empName = "PAGO DE EMPRESA " . strtoupper($getEmpName[0]['NOMBRE']) . ":";
        $facID = self::$db->query_select("cllg_factura", sprintf("NUMERO='%s'", $strNumero));
        $cargo = self::$db->query_select("cllg_mov_cargo", sprintf("FK_FACTURA='%s'", $facID[0]['ID']));

        $i = 0;
        while ($i < count($cargo)) {
            $det = self::$db->query_select("cllg_cargo", sprintf("ID='%s'", $cargo[$i]['FK_CARGO']));
            $acc = self::$db->query_select("cllg_account", sprintf("ID='%s'", $det[0]['FK_ACCOUNT']));
            $studName = self::$db->query_select("cllg_student", sprintf("ID='%s'", $acc[0]['FK_STUDENT']));
            $studName = $studName[0];
            $desc[$i] = $det[0]['DESCRIPTION'] . " del alumno " . $studName['FIRST_NAME'] . " " . $studName['LAST_NAME'];
            $monto[$i] = $cargo[$i]['MONTO'];
            $i++;
        }

        $pdf = new TCPDF("", "mm", "LETTER", true, 'UTF-8', false);
        $pdf->setPageOrientation("");
        $pdf->setPrintHeader(false);
        $pdf->setPrintFooter(false);
        $pdf->SetMargins(0, 0, 0);

        // set font
        $pdf->SetFont('helveticaB', '', 10);

        // add a page
        $pdf->AddPage();

        // set cell padding
        $pdf->setCellPaddings(0, 0, 0, 0);

        // set cell margins
        $pdf->setCellMargins(0, 0, 0, 0);

        // set color for background
        $pdf->SetFillColor(0, 0, 0, 0);

        //Serie y Numero 
        $pdf->MultiCell(20, 1, $strSerie . ' - ' . $strNumero, 0, 'L', false, 1, 125, 6, true);
        //Fecha
        $pdf->MultiCell(60, 1, $strFecha, 0, 'L', 0, 1, 100, 21, true);
        //Detalle
        $intY = 30;
        $index = 0;
        
        $pdf->MultiCell(90, 1, $empName, 0, 'L', 0, 1, 15, $intY, true);
        $intY += 4;
        while ($index < count($desc)) {
            $pdf->MultiCell(120, 1, $desc[$index], 0, 'L', 0, 1, 15, $intY, true);
            $pdf->MultiCell(20, 1, number_format($monto[$index], 2), 0, 'R', 0, 1, 127, $intY, true);
            $intY += 8;
            $index++;
        }

        $pdf->Output("Factura_$facNo.pdf", 'I');
    }

}

?>
